package cc.z8g.browser.utils;

import android.os.Handler;
import android.os.Looper;

import androidx.annotation.NonNull;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Scheduler;
import io.reactivex.rxjava3.schedulers.Schedulers;

/**
 * ThreadPool
 *
 * @author zhaoxuyang.net
 * @since 2023-10-12
 */
public class ThreadPool {

    /** 数据库操作执行器 */
    private static final ExecutorService mDatabaseExecutor = Executors.newSingleThreadExecutor();
    /** 磁盘操作执行器 */
    private static final ExecutorService mDiskExecutor = Executors.newSingleThreadExecutor();
    /** 单线程、可以延迟的任务 */
    private static final ScheduledExecutorService mDelayExecutor = Executors.newSingleThreadScheduledExecutor();
    /** 单线程、可以延迟的任务 */
    private static final ExecutorService mNetworkExecutor = new ThreadPoolExecutor(1, 4, 60, TimeUnit.SECONDS, new LinkedTransferQueue<>());
    /** 临时使用 */
    private static final Scheduler mIOScheduler = Schedulers.from(mDatabaseExecutor);
    /** 临时使用 */
    private static final Scheduler mDiskScheduler = Schedulers.from(mDatabaseExecutor);
    /** 临时使用 */
    private static final Scheduler mNetworkScheduler = Schedulers.from(mNetworkExecutor);
    /** 临时使用 */
    private static final Scheduler mMainScheduler = AndroidSchedulers.mainThread();
    /** 主线程 */
    private static final Handler mMainHandler = new Handler(Looper.getMainLooper());

    /** 数据库操作等 */
    public static Scheduler getDBScheduler() {
        return mIOScheduler;
    }

    /** 磁盘操作 */
    public static Scheduler getDiskScheduler() {
        return mDiskScheduler;
    }

    public static Scheduler getNetworkScheduler() {
        return mNetworkScheduler;
    }
    public static ExecutorService getNetworkExecutor() {
        return mNetworkExecutor;
    }

    /** 数据库操作等 */
    public static Scheduler getMainScheduler() {
        return mMainScheduler;
    }


    /** 执行一个数据库操作任务 */
    public static void postDB(@NonNull Runnable dbTask) {
        mDatabaseExecutor.execute(dbTask);
    }

    public static void postSingle(@NonNull Runnable task) {
        mDelayExecutor.execute(task);
    }

    public static void postSingle(long delay, TimeUnit unit, @NonNull Runnable task) {
        mDelayExecutor.schedule(task, delay, unit);
    }

    public static <V> void postSingle(long delay, TimeUnit unit, @NonNull Callable<V> callable) {
        mDelayExecutor.schedule(callable, delay, unit);
    }

    public static Handler getMainHandler() {
        return mMainHandler;
    }

    public static void postUI(@NonNull Runnable runnable) {
        Handler main = mMainHandler;
        if (Thread.currentThread() == main.getLooper().getThread()) {
            runnable.run();
        } else {
            main.post(runnable);
        }
    }

    public static void postDisk(@NonNull final Runnable runnable) {
        mDiskExecutor.execute(runnable);
    }

    public static void postIO(@NonNull final Runnable runnable) {
        mNetworkExecutor.execute(runnable);
    }

}
